class MyBlockingQueue{
    public long[] data; //阻塞队列可以由数组来实现
    //构造方法，去初始化数组
    public MyBlockingQueue(int  capacity){
       data=new long[capacity];
    }
    //阻塞队列由环形数组来实现
    //用head，tail去标记头和尾
    public int head=0;
    public int tail=0;
    public int size=0; //用size去记录此时环形数组中有效元素的个数
    public Object locker=new Object(); //定义一个锁对象
    //添加元素
    public void put(long elem){
        synchronized (locker){
            //先判断数组是否满了，满了就阻塞
            if (size== data.length){
                try {
                    locker.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            //数组没有满，直接将元素添加到tail的位置
            data[tail]=elem;
            tail++;
            if(tail>=data.length){
                tail=0;
            }
            size++;
            locker.notify();
        }
    }
    //取出元素
    public long take() throws InterruptedException {
        synchronized (locker){
            //先判断数组是否为空，为空就阻塞
            if (size==0){
                locker.wait();
            }
            //数组不为空，就取出head位置的元素，然后head++(逻辑上把删除)
            long ret=data[head];
            head++;
            if (head>=data.length){
                head=0;
            }
            size--;
            locker.notify();
            return ret;
        }

    }
}
public class Demo26 {
    public static void main(String[] args) {
          MyBlockingQueue queue =new MyBlockingQueue(1000);
          //生产者
          Thread t1=new Thread(()->{
              long n=0;
              while (true){
                  queue.put(n);
                  System.out.println("生产了数据： "+n);
                  try {
                      Thread.sleep(1000);
                  } catch (InterruptedException e) {
                      throw new RuntimeException(e);
                  }
                  n++;
              }
          });
          //消费者
          Thread t2=new Thread(()->{
              while (true){
                  try {
                      long n= queue.take();
                      System.out.println("消费了数据： "+n);
                  } catch (InterruptedException e) {
                      throw new RuntimeException(e);
                  }

              }
          });
          t1.start();
          t2.start();
    }
}
